﻿using System.Html;
using System;
using System.Collections.Generic;
using Db7.Collections;

namespace Db7
{
    public class VirtualElement
    {

        #region Constants
        public const string _g = "_g";
        public const string IE = "Microsoft Internet Explorer";
        public const string Firefox = "Netscape";
        #endregion

        #region Methods

        public void RenderInside(string ContainerID)
        {
            if (RenderContext.ElementLookup == null) RenderContext.ElementLookup = new Dictionary<string, VirtualElement>();
            RenderContext.ElementLookup[ContainerID] = this;
            this.RootContainerId = ContainerID;
            RenderContext rc = new RenderContext(ContainerID);
            DoDefaultRender(rc, this);
            rc.RootElement.InnerHTML = rc.sw.ToString();
        }

        

        public void RegisterEventHandlers(RenderContext rc)
        {
        }

        private void SetTextToItself()
        {
            this.Text_D = this.Text_D;
        }

        public virtual void DoDefaultRender(RenderContext rcIn, VirtualElement ve)
        {
            //Date nw = Date.Now;
            //RootContainerId = rcIn.RootID;
            if (Init != null) Init();
            if (PreRender != null) PreRender();
            if (Text_DB != null)
            {
                Text_DB.AddOnUpdateNotification(SetTextToItself);  
            }
            int cnt = rcIn.Counts.Pop();
            this.Index = cnt;
            rcIn.Counts.Push(cnt + 1);
            rcIn.sw.Append("<" + ve.Tag);
            rcIn.sw.Append(" " + _g + "='" + cnt + "'");
            if (ve.Classes != null)
            {
                rcIn.sw.Append(" class='" + ve.Classes.ToString() + "'");
            }
            if (ve.Dimensions != null)
            {
                ve.Dimensions.AddToStyles(ve.StylesNN);
            }
            if (ve.Styles != null)
            {
                rcIn.sw.Append(" style='" + Util.StringXString2String(ve.Styles, ":", ";") + "'");
            }
            if (ve.Attributes != null)
            {
                //Util.Debug();
                rcIn.sw.Append(" " + ve.Attributes.ToString());
            }
            rcIn.sw.Append(">");
            string content = null;
            if (ve.Text != null)
            {
                content = ve.Text;
            }
            else if (ve.Text_D != null)
            {
                content = ve.Text_D;
            }
            else if (ve.Children != null)
            {
                int childCount = 0;
                foreach (VirtualElement child in ve.Children)
                {
                    child.Parent = this;
                    rcIn.Counts.Push(childCount);
                    child.DoDefaultRender(rcIn, child);
                    childCount++;
                    rcIn.Counts.Pop();
                }
            }
            rcIn.sw.Append(content);
            rcIn.sw.Append("</" + ve.Tag + ">");
            //return rc;
        }
        #endregion

        #region Public Actions
        public Action Init;
        public Action PreRender;
        #endregion

        #region Public Fields / Properties

        public StringAttributes Attributes;

        public StringAttributes AttributesNN
        {
            get
            {
                if (Attributes == null) Attributes = new StringAttributes();
                return Attributes;
            }
        }

        public List<VirtualElement> Children;

        public List<VirtualElement> ChildrenNN
        {
            get
            {
                if (Children == null) Children = new List<VirtualElement>();
                return Children;
            }
        }

        public DimensionStyle Dimensions;

        public DimensionStyle DimensionsNN
        {
            get
            {
                if (Dimensions == null) Dimensions = new DimensionStyle();
                return Dimensions;
            }
        }

        public int Index;

        public VirtualElement Parent;

        //private Element _physicalElement;
        public Element PhysicalElement
        {
            get { 
                return Queries.GetElement(this); 
            }
        }

        public string Tag;

        //public string GUID;

        //public ObservableCollection<string> Classes = new ObservableCollection<string>();

        public Tags Classes;
        public Tags ClassesNN
        {
            get
            {
                if (Classes == null) Classes = new Tags();
                return Classes;
            }
        }

        public Dictionary<string, string> Styles;
        public Dictionary<string, string> StylesNN
        {
            get
            {
                if (Styles == null) Styles = new Dictionary<string, string>();
                return Styles;
            }
        }

        public string RootContainerId;

        public string Text;

        public StringBinder Text_DB;

        public string Text_D
        {
            get { return StringBinder.Get(Text_DB); }
            set {
                Text_DB = StringBinder.Set(Text_DB, value);
                this.PhysicalElement.InnerHTML = value;
            }
        }
        #endregion

        #region Private State

        #endregion

        public VirtualElement()
        {
            //this.Render = delegate(RenderContext rc)
            //{
            //    this.DoDefaultRender(rc, this);
            //};
            
        }

        private int? _guid;

        public int GUID
        {
            get
            {
                if (_guid == null)
                {
                    _guid = RenderContext.ControlCounter;
                    RenderContext.ControlCounter++;
                    
                }
                return (int)_guid;
            }
        }

    }

    
}
